﻿using Core.Utility;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Core.Container
{
    public class NameContainer<T> where T : class
    {
        ConcurrentDictionary<string, T> Items = new ConcurrentDictionary<string, T>();

        public string Folder { get; set; } = "Container";
        private string Path = string.Empty;

        /// <summary>
        /// 容器的名称
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 初始化
        /// </summary>
        /// <returns></returns>
        public bool Init()
        {
            bool result;
            try
            {
                Path = string.Format(@"{0}\Config\{1}\{2}.xml", Environment.CurrentDirectory, Folder,
                                               string.IsNullOrEmpty(Name) ? this.GetType().Name : Name);
                var keys = SerializerXml<List<string>>.Read(Path);
                foreach (var v in keys)
                {
                    if (!Items.ContainsKey(v))
                    {
                        Items.TryAdd(v, default(T));
                    }
                }
                result = true;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message, ex);
            }
            return result;
        }

        /// <summary>
        /// 保存所有键的名称
        /// </summary>
        /// <returns></returns>
        bool SaveConfig()
        {
            try
            {
                var keys = GetKeys();
                SerializerXml<List<string>>.WriteObject(GetKeys(), Path);
                return true;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message, ex);
            }
        }

        public T Get(string key)
        {
            T result = null;
            try
            {
                if (Items.ContainsKey(key))
                {
                    result = Items[key];
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message, ex);
            }
            return result;
        }

        public bool Add(string key, T value)
        {
            bool result = false;
            try
            {
                Items.AddOrUpdate(key, value, (s, i) => value);
                result = true;
                SaveConfig();
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message, ex);
            }
            return result;
        }
        
        public bool Remove(string key)
        {
            bool result = false;
            try
            {
                if (Items.ContainsKey(key))//如果存在则删除
                {
                    Items.TryRemove(key, out T value);
                    result = true;
                    SaveConfig();
                }
                else
                {
                    result = true;
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message, ex);
            }
            return result;
        }

        public List<string> GetKeys()
        {
            List<string> result = new List<string>();
            try
            {
                result = Items.Keys.ToList();
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message, ex);
            }
            return result;
        }

        public List<T> GetValues()
        {
            List<T> values = new List<T>();
            try
            {
                values = Items.Values.ToList();
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message, ex);
            }
            return values;
        }
    }
}
